package com.zmj.dubboannotation.consumermobile.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zmj.commoncore.constant.RedisConstant;
import com.zmj.commoncore.dto.CartDTO;
import com.zmj.commoncore.utils.JsonUtil;
import com.zmj.commoncore.utils.MemberIdUtil;
import com.zmj.dubboannotation.consumermobile.redis.RedisUtil;
import com.zmj.dubboannotation.serviceapi.enums.MallEnum;
import com.zmj.dubboannotation.serviceapi.model.MemberActionLog;
import com.zmj.dubboannotation.serviceapi.model.MemberProductCollection;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 拦截用户行为 缓存入redis
 *
 * 定时持久化到db
 *
 * @author zmj
 * @version 2018/7/03
 */
@Aspect
@Component
@Slf4j
@Order(2)
public class MemberActionLgAspect {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 拦截用户浏览商品 收藏商品 添加购物车的行为
     */
    @Pointcut(value = "execution(public * com.zmj.dubboannotation.consumermobile.controller.ProductController.getProduct(..)) ||" +
            "execution(public * com.zmj.dubboannotation.consumermobile.controller.ProductCollectionController.create(..)) ||" +
            "execution(public * com.zmj.dubboannotation.consumermobile.controller.CartController.create(..)) " )
    public void actionAll() {
    }

    /**
     * AfterReturning获取不到入参值 所以用 Around 环绕通知
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("actionAll()")
    public Object doToken(ProceedingJoinPoint joinPoint) throws Throwable {

        Object result = "";

        String memberId = getCookieMemberId();

     /*   //获取类名
        String className = joinPoint.getTarget().getClass().getName();
        //方法名
        String methodName = joinPoint.getSignature().getName();*/

        String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        Object[] args = joinPoint.getArgs();
        List<String> paramsList = Arrays.asList(parameterNames);
        String declaringTypeName = joinPoint.getSignature().getDeclaringTypeName();
        int index = 0;
        Object productId = null;
        //用户行为(1浏览,2收藏,3加入购物车)
        int action = 0;

        //收藏
        if(declaringTypeName.contains("ProductCollectionController")) {
            for (int i = 0; i < paramsList.size(); i++) {
                Object o = paramsList.get(i);
                if(StringUtils.equals(o.toString(),"collection")) {
                    index = i;
                }
            }
            MemberProductCollection productCollection = JsonUtil.toJavaBean(args[index], MemberProductCollection.class);
            productId = productCollection.getProductId();
            action = MallEnum.ACTION_COLLECT.getCode();
        //浏览
        }else if (declaringTypeName.contains("ProductController")) {
            for (int i = 0; i < paramsList.size(); i++) {
                Object o = paramsList.get(i);
                if (StringUtils.equals(o.toString(), "skuId")) {
                    index = i;
                }
            }
            productId = args[index];
            action = MallEnum.ACTION_LOOK.getCode();

        }else if (declaringTypeName.contains("CartController")) {

            for (int i = 0; i < paramsList.size(); i++) {
                Object o = paramsList.get(i);
                if (StringUtils.equals(o.toString(), "cartDTO")) {
                    index = i;
                }
            }
            CartDTO cartDTO = JsonUtil.toJavaBean(args[index], CartDTO.class);
            productId = cartDTO.getProductId();
            action = MallEnum.ACTION_ADD_CART.getCode();
        }

        /** 执行目标方法 */
        result = joinPoint.proceed();

        MemberActionLog memberActionLog = new MemberActionLog();

        if (null != productId) {
            memberActionLog.setSkuProductId(String.valueOf(String.valueOf(productId)));
        }
        memberActionLog.setMemberId(String.valueOf(memberId));
        memberActionLog.setAction(Integer.valueOf(action).byteValue());
        memberActionLog.setCreateTime(new Date());

        String str = objectMapper.writeValueAsString(memberActionLog);
        redisUtil.leftPush(RedisConstant.MEMBER_ACTION_PREFIX,str);

        return result;
    }

    private String getCookieMemberId() throws Exception {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String memberId = MemberIdUtil.getCookieMemberId(request);
        if(StringUtils.isBlank(memberId)) {
            return "0";
        }
        return memberId;
    }

}
